﻿/*
 * Environment
 * 
 * initial implementation : 28.5.2011
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
//using System.Linq;
//using System.Text;
using System.Windows.Markup;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using Petra.Gis.Support;
using Petra.Gis.DocumentServices;
using Petra.Gis.ReferenceSystemServices;


namespace Petra.Gis
{


  /// <summary>
  /// also represents Coordinate system search engine
  /// that searches in <c>CoordinateSystemLibrary</c>
  /// for existing/predefined coordinate systems.
  /// </summary>
  public static partial class Environment
  {



    /// <summary>
    /// search coordinate system by given parameters: authority name, code and storage units name
    /// </summary>
    /// <param name="authority">coordinate system authority name</param>
    /// <param name="code">coordinate system code</param>
    /// <param name="storageUnitName">name of storage units</param>
    /// <returns>if any predefined coordinate system in cache meets search criteria
    /// then first matching coordinate system is returned. If no match, returns null.
    /// </returns>
    public static CoordinateSystem SearchSrsBy(string authority, string code, string storageUnitName)
    {

      //CoordinateSystem result = null;

      // search first in coordinate systems...
      //CoordinateSystem cs = srssearchBy(authority, code);
      CoordinateSystem cs = Environment.Libraries.SRSLibrary.SearchBy(authority, code);
      if (cs != null)
        return _resolveNamedCsStorageUnits(cs, storageUnitName);

      // ok, not found
      // try search in transforms collection...
      //foreach (SRSTransform t in SRSTransform.Transforms)
      //{
      //  if (t.Source.Metadata.Authority == authority && t.Source.Metadata.AuthorityCode.ToString() == code)
      //    //result =  t.Source;
      //    return _resolveNamedCsStorageUnits(t.Source, storageUnitName);

      //  else if (t.Target.Metadata.Authority == authority && t.Target.Metadata.AuthorityCode.ToString() == code)
      //    //result = t.Target;
      //    return _resolveNamedCsStorageUnits(t.Target, storageUnitName);
      //}

      // if coordinate system found
      // and units are specified as input parameter
      // try change coordinate system units
      //if (result != null && storageUnitName != "")
      //{
      //  // try resolve storage units..
      //  return resolveNamedCsStorageUnits(result, storageUnitName);
      //}

      return null;
    }





    //private static CoordinateSystem srssearchBy(string authority, string code)
    //{
    //  foreach (CoordinateSystem cs in Environment.Libraries.SRSLibrary.CoordinateSystems)
    //  {
    //    if (cs.Metadata.Authority == authority && cs.Metadata.AuthorityCode.ToString() == code)
    //      return cs;
    //  }
    //  return null;

    //}







    /// <summary>
    /// if coordinate system found and storage unist differs from search request
    /// coordinate system definition is updated by requested storage units
    /// </summary>
    /// <param name="cs">coordinate system to update</param>
    /// <param name="inputStorageUnitName">name of storage units to replace original with</param>
    /// <returns>updated coordinate system. If requested units not found or units are different (angular x distance) returns null</returns>
    private static CoordinateSystem _resolveNamedCsStorageUnits(CoordinateSystem cs, string inputStorageUnitName)
    {
      // if coordinate system found
      // and units are specified as input parameter
      if (inputStorageUnitName == "")
        return cs;

      // try change coordinate system units
      // try resolve storage units..
      // search for unit by given name
      MeasureUnit su = MeasureUnit.Parse(inputStorageUnitName);

      // if unit not found, return null
      if (su == null)
        return null;

      // if some unit found, check for sure
      // if type is same (angular or distance)
      if (cs.Unit.GetType() != su.GetType())
        return null;
      //throw new ArgumentException("specified coordinate system in:" + csInfo +
      //                            " has " + su.GetType().ToString() + " storage units  and " +
      //                            " found coordinate system has " + result.Unit.GetType().ToString());

      // if given unit is different from cs one
      // clone cs and replace
      if (!cs.Unit.EqualParams(su))
      {
        CoordinateSystem result = cs.Clone();
        result.Unit = su;
        return result;
      }
      else
        // or leave and return cs untouched
        return cs;

    }


  }

}
